/**
 * 骗子酒馆
 * @author: mitu2
 * @param options
 */
export function init(options = {}) {
    const { currentUser } = window.Label || {
        currentUser: window.location.hostname + "_Player_" + (Math.floor(Math.random() * 10000))
    }
    const baseLT = {
        player: currentUser,
        baseUrl: "https://game.metoo.ink",
        globalName: "LT",
        op: {},
    }
    const LT = Object.assign({}, baseLT, options)
    const LOG = (msg, level = "#42c02e") => {
        console.log(
            `%c[LiarTavern]%c${ msg }`,
            'padding: 2px 1px; border-radius: 3px 0 0 3px; color: #fff; background: #606060; font-weight: bold;',
            `padding: 2px 1px; border-radius: 0 3px 3px 0; color: #fff; background: ${ level };`,
        )
    }
    const LOG_ERR = (msg) => LOG(msg, "#fb415e")
    const doApi = (path, params) => {
        params = params ? `&${ params }` : ""
        return fetch(`${ LT.baseUrl }/${ path }?player=${ LT.player }${ params }`)
            .then(resp => new Promise((resolve, reject) => {
                if (resp.status !== 200) reject(resp)
                resolve(resp)
            })
                .catch(err => {
                    err.json().then(json => {
                        LOG_ERR(json.message)
                    })
                    throw err
                }))
    }
    const APIS = {
        play: (uuid) => uuid ? doApi(`api/liar-tavern-game/${ uuid }/play`) : doApi(`api/liar-tavern-game/play`),
        watch: (uuid, version) => doApi(`api/liar-tavern-game/${ uuid }/watch`, `version=${ version }`),
        cards: (uuid, useCards) => doApi(`api/liar-tavern-game/${ uuid }/cards`, `use=${ useCards }`),
        bang: (uuid) => doApi(`api/liar-tavern-game/${ uuid }/bang`)
    }
    const PRIVATE = {
        watchInterval: -1,
        waitPlayer: '',
        NONE: () => {},
    }
    LT.play = async function (roomId) {
        const playResp = await APIS.play(roomId)
        console.clear()
        const {
            creator, uuid
        } = await playResp.json()
        let ots = ''
        if (LT.baseUrl !== baseLT.baseUrl) {
            ots = `, baseUrl: '${ LT.baseUrl }'`
        }
        if (creator === LT.player) {
            LOG(`已创建一个酒馆, 需满足4人开始游戏, 邀请方式对方控制台输入> import("${ LT.baseUrl }/liar-tavern-game.js").then(({init}) => init({uuid: '${ uuid }'${ ots }}))`)
        } else {
            LOG(`已加入${ creator }的酒馆, 需满足4人开始游戏, 邀请方式对方控制台输入> import("${ LT.baseUrl }/liar-tavern-game.js").then(({init}) => init({uuid: '${ uuid }'${ ots }}))`)
        }
        if (PRIVATE.watchInterval || PRIVATE.watchInterval > 0) {
            clearInterval(PRIVATE.watchInterval)
        }
        PRIVATE.uuid = uuid
        let version = 0
        PRIVATE.watchInterval = setInterval(async () => {
            const watchResp = await APIS.watch(PRIVATE.uuid, version)
            const {
                events, lastVersion, playerDataList
            } = await watchResp.json()
            PRIVATE.playerDataList = playerDataList
            const refreshItems = (record) => {
                let op = {}
                let _record = record || []
                for (let recordElement of _record) {
                    let size = 1
                    while (op[`${ recordElement }_${ size }`]) {
                        ++size
                    }
                    op[`${ recordElement }_${ size }`] = {
                        key: recordElement,
                        size: size
                    }
                }
                LT.op = op
            }
            for (let event of events) {
                const { type, player, record } = event
                switch (type) {
                    case "PLAYER_JOIN":
                        if (player === LT.player) {
                            LOG(`${ player } 加入了酒馆 <- 这个是你`)
                        } else {
                            LOG(`${ player } 加入了酒馆`)
                        }
                        break
                    case "PLAYER_LEAVE":
                        LOG_ERR(`${ player } 退出了酒馆`)
                        break
                    case "GAME_START":
                        LOG_ERR(`游戏开始 注意👉(?是对方位置的牌 K,Q,J,A分别有6个, S是万能牌仅有2个)`)
                        break
                    case "GAME_END":
                        if (PRIVATE.watchInterval || PRIVATE.watchInterval > 0) {
                            clearInterval(PRIVATE.watchInterval)
                        }
                        LOG_ERR(`游戏结束, 胜利者是: ${ record }`)
                        break
                    case "PLAYER_PLAY_CARDS":
                        if (player === LT.player) {
                            LOG(`您打出了 [ ${ record } ]`)
                            const myself = playerDataList.findLast(it => it.name === LT.player)
                            myself && refreshItems(myself.items)
                        } else {
                            LOG(`${ player } 打出了 [ ${ record } ]`)
                        }
                        break
                    case "PLAYER_SHOOT":
                        LOG(`${ player } 对自己的大脑门开了一枪 (${ record }/6)`)
                        break
                    case "PLAYER_DEATH":
                        LOG_ERR(`倒霉催${ player }盖了帽了`)
                        break
                    case "PLAYER_BANG":
                        if (player === LT.player) {
                            LOG(`你对${ PRIVATE.preWaitPlayer }发出质疑觉得出的牌有假`)
                        } else {
                            LOG(`${ player }觉得${ PRIVATE.preWaitPlayer }有诈`)
                        }
                        LOG(`揭秘${ record.player }出的牌是[ ${ record.useItems } ]`)
                        break
                    case "WAIT_PLAYER_OPERATE":
                        PRIVATE.preWaitPlayer = PRIVATE.waitPlayer
                        PRIVATE.waitPlayer = player
                        if (player === LT.player) {
                            if (record === 1) {
                                LOG(`这轮您第一个出牌${ LT.globalName }.cards(${ LT.globalName }.op.浏览器提示)出牌, 例子${ LT.globalName }.cards(${ LT.globalName }.op.K_2, ${ LT.globalName }.op.J_1)是将自己的2个K和一个J打出`)
                            } else {
                                LOG(`轮到您操作了可通过${ LT.globalName }.bang()拍桌子质疑上一家或者打出牌${ LT.globalName }.cards(${ LT.globalName }.op.浏览器提示)例子${ LT.globalName }.cards(${ LT.globalName }.op.K_2, ${ LT.globalName }.op.J_1)`)
                            }
                        } else {
                            LOG(`轮到了${ player }操作`)
                        }
                        break
                    case "REFRESH_ITEM":
                        const { key, playItems } = record
                        refreshItems(playItems)
                        LOG(`小B宅子在线发牌, 本轮关键牌是[ ${ key } ]. 下面是玩家牌情况 可通过${ LT.globalName }.show()主动查看当前牌局玩家牌`)
                        LT.show()
                        break
                }
            }
            version = lastVersion
        }, 2000)
    }

    LT.cards = function (...useCards) {
        const uks = useCards.flatMap(card => Array(card.size).fill(card.key))
        APIS.cards(PRIVATE.uuid, uks).then(PRIVATE.NONE)
    }

    LT.bang = function () {
        APIS.bang(PRIVATE.uuid).then(PRIVATE.NONE)
    }

    LT.show = function () {
        if (!PRIVATE.playerDataList) return
        const ot = PRIVATE.playerDataList
            .filter(it => it.status === 'ALIVE')
            .map(it => `${ it.name } => [ ${ it.items.join(', ') } ]`)
            .join(', ')
        LOG(ot)
    }
    LOG(`${ LT.player }. 骗子酒馆控制台版本初始化完成, 项目地址: https://gitcode.com/mitu2/fish-game 欢迎提出问题`)
    LOG(`控制台输入${ LT.globalName }.play()即可探索`)
    if (LT.uuid) {
        LT.play(LT.uuid).then()
    }
    window[LT.globalName] = LT
}